package vericopServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Properties;

import security.keyManagement.KeyStoreManager;
import utils.PropertiesUtils;
import connection.DatabaseConnection;
import connection.TCPSecureClientSocket;
import connection.exception.ConnectionResetException;
import connection.exception.PropertiesUndefinedException;

public class VericopData {

	private static VericopData _vericopDataSingleton;
	
	private DatabaseConnection _databaseConnection;
	
	private KeyStoreManager _vericopKeyManager;
	
	private TCPSecureClientSocket _tcpSocket;
	
	public VericopData(String password) throws ConnectionResetException{
		
		_vericopDataSingleton = this;
		
		try {
			_vericopKeyManager = new KeyStoreManager(password, true, false);
			_databaseConnection = new DatabaseConnection(_vericopKeyManager, "config/VERICOPDBConf.properties");
			
			Properties vericopProperties = PropertiesUtils.getPropertiesFromFile("config/VERICOP.properties");
			
			String certcopIp = vericopProperties.getProperty("certcopIp");
			int certcopPort = Integer.parseInt(vericopProperties.getProperty("certcopPort"));
			InetSocketAddress remoteAddr = new InetSocketAddress(certcopIp, certcopPort);
			
			int vericopBindPort = Integer.parseInt(vericopProperties.getProperty("vericopPort"));			
			
			_tcpSocket = new TCPSecureClientSocket(remoteAddr, vericopBindPort);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (PropertiesUndefinedException e) {
			e.printStackTrace();
		}				
	}

	public static VericopData getInstance() {
		return _vericopDataSingleton;
	}

	public KeyStoreManager getKeyStoreManager() {
		return _vericopKeyManager;
	}
	
	public DatabaseConnection getDatabaseConnection(){
		return _databaseConnection;
	}
	
	public void send(Object obj) throws ConnectionResetException{
		_tcpSocket.send(obj);
	}
	
	public Object receive() throws ConnectionResetException{
		return _tcpSocket.receive();
	}
	
	/**
	 * Stores the received signature on the VERICOP Database.
	 * 
	 * @param serial The serial number of the signature archive.
	 * @param signature The signature
	 * @return Whether or not the operation was successful
	 */
	public Boolean storeSignature(Integer serial, String signature) {
	    int status = getDatabaseConnection().addVericopSignature(serial.toString(), signature);
	    
	    return (status >= 0 ? true : false);
	}
	
	/**
	 * Checks if the supplied signature value matches the one on
	 * the VERICOP database.
	 * 
	 * @param serial The serial number of the supplied signature.
	 * @param signature The signature
	 * @return Whether or not the operation was successful
	 */
	public Boolean checkSignature(Integer serial, String signature) {
	    
	    // Obtain the Stored Signature
	    String storedSig = getDatabaseConnection().getVericopSignature(serial.toString());
	    
	    // Verify if it matches the one on the DB
	    Boolean res = signature.equals(storedSig);
	    
	    return res;
	}
}
